package timing.ukulele.storage.util;

import org.apache.commons.exec.CommandLine;
import org.apache.commons.exec.DefaultExecutor;
import org.apache.commons.io.FileUtils;
import org.springframework.boot.system.ApplicationHome;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Semaphore;

/**
 * 基于libreoffice实现的PDF转换
 */
@Component
public class PdfConvertUtils {

    private String getWorkPath() {
        ApplicationHome home = new ApplicationHome(getClass());
        File jarFile = home.getSource();
        return jarFile.getParentFile().toString() + File.separator + "convert";
    }

    public void clearWorkDir() {
        String wordDir = getWorkPath();
        try {
            FileUtils.cleanDirectory(new File(wordDir));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * @param fileName 文件名称
     * @param input    文件流
     */
    public File toPdf(String fileName, InputStream input) {
        long start = System.currentTimeMillis();
        String workDir = getWorkPath();
        File dir = new File(workDir);
        if (!dir.exists()) {
            dir.mkdir();
        }
        try {
            File file = new File(workDir + File.separator + fileName);
            OutputStream os = Files.newOutputStream(file.toPath());
            int bytesRead = 0;
            byte[] buffer = new byte[1024];
            while ((bytesRead = input.read(buffer)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.close();
            input.close();
            System.out.println("源文件：" + file.getPath());
            System.out.println("目标文件夹：" + workDir);
            String command;
            String osName = System.getProperty("os.name");
            System.out.println("系统名称：" + osName);
            if (osName.contains("Windows")) {
                command = "soffice --invisible --headless --convert-to pdf " + file.getPath() + " --outdir " + workDir;
                System.out.println(command);
            } else {
                command = "libreoffice7.4 --convert-to pdf:writer_pdf_Export " + file.getPath() + " --outdir " + workDir;
            }
            executeCommand(command);
        } catch (Exception e) {
            e.printStackTrace();
        }
        long end = System.currentTimeMillis();
        System.out.println("转换文件耗时：" + (end - start) + "毫秒");

        File file = new File(workDir + File.separator + fileName.substring(0, fileName.lastIndexOf(".")) + ".pdf");
        return file;
    }

    public void toPdf(String filePath, String targetFolder) throws IOException, InterruptedException {
        long start = System.currentTimeMillis();
        System.out.println("源文件：" + filePath);
        System.out.println("目标文件夹：" + targetFolder);
        String command;
        String osName = System.getProperty("os.name");
        System.out.println("系统名称：" + osName);
        if (osName.contains("Windows")) {
            command = "soffice --invisible --headless --convert-to pdf " + filePath + " --outdir " + targetFolder;
            System.out.println(command);
        } else {
            command = "libreoffice7.4 --convert-to pdf:writer_pdf_Export " + filePath + " --outdir " + targetFolder;
        }
        executeCommand(command);
        long end = System.currentTimeMillis();
        System.out.println("转换文件耗时：" + (end - start) + "毫秒");
    }

    /**
     * 获取pdf文件的访问URL
     *
     * @param fileUrl
     * @return
     */
    public String getPDFUrl(String fileUrl) {
        int dotIndex = fileUrl.lastIndexOf(".");
        return fileUrl.substring(0, dotIndex) + ".pdf";
    }

    /**
     * 获取png文件的访问URL
     *
     * @param fileUrl
     * @return
     */
    public List<String> getPngUrl(String fileUrl, int pages) {
        if (pages < 1) {
            return null;
        }
        int dotIndex = fileUrl.lastIndexOf(".");
        List<String> list = new ArrayList<>();
        for (int i = 0; i < pages; i++) {
            list.add(fileUrl.substring(0, dotIndex) + "_" + (i + 1) + ".png");
        }
        return list;
    }

    public List<String> getSvgUrl(String fileUrl, int pages) {
        if (pages < 1) {
            return null;
        }
        int dotIndex = fileUrl.lastIndexOf(".");
        List<String> list = new ArrayList<>();
        for (int i = 0; i < pages; i++) {
            list.add(fileUrl.substring(0, dotIndex) + "_" + (i + 1) + ".svg");
        }
        return list;
    }

    /**
     * 获取文件名 不带后缀
     *
     * @param fileUrl
     * @return
     */
    public static String fileName(String fileUrl) {
        int dotIndex = fileUrl.lastIndexOf(".");
        int lastSeparator = fileUrl.lastIndexOf(File.separator);
        if (lastSeparator == -1) {
            return fileUrl.substring(0, dotIndex);
        } else {
            return fileUrl.substring(lastSeparator + 1, dotIndex);
        }
    }

    private void executeCommand(String command) throws InterruptedException, IOException {
        System.err.println("即将执行转换命令");
        Semaphore semaphore = new Semaphore(1);
        semaphore.acquire();
//        ExecuteResultHandler erh = new ExecuteResultHandler() {
//            @Override
//            public void onProcessComplete(int i) {
//                System.err.println("转换命令执行完成");
//                semaphore.release();
//            }
//
//            @Override
//            public void onProcessFailed(ExecuteException e) {
//                semaphore.release();
//                System.err.println("转换命令执行异常");
//                e.printStackTrace();
//            }
//        };
        DefaultExecutor exec = DefaultExecutor.builder().get();
        exec.execute(CommandLine.parse(command));
    }
}
